package org.demos.client;

import java.util.UUID;

import lombok.Data;
import lombok.ToString;
import org.demos.client.http.HttpSender;
import org.demos.client.pojo.HeartbeatRequest;
import org.demos.client.pojo.HeartbeatResponse;
import org.demos.client.pojo.RegisterRequest;
import org.demos.client.pojo.RegisterResponse;

/**
 * 在业务服务上被创建和启动，负责跟 register-server 进行通信
 *
 * @author bing.zhang06@hand-china.com 2021/10/26 10:55
 **/
public class RegisterClient {
    /**
     * 服务名
     */
    public static final String SERVICE_NAME = "inventory-service";

    /**
     * 主机 IP
     */
    public static final String IP = "192.168.31.207";

    /**
     * 主机名
     */
    public static final String HOSTNAME = "inventory01";

    /**
     * 端口号
     */
    public static final int PORT = 9000;

    /**
     * 服务实例id
     */
    private String serviceInstanceId;

    /**
     * http通信组件
     */
    private HttpSender httpSender;

    public RegisterClient() {
        this.serviceInstanceId
                = UUID.randomUUID().toString().replace("-", "");
        this.httpSender = new HttpSender();
    }

    /**
     * 业务服务启动这个组件,主要做两件事：
     * 1.向 register-server 注册服务
     * 2.向 register-server 发送心跳(表明自己仍存活)
     */
    public void start() {
        try {
            // 1.启动注册服务线程进行工作
            RegisterClientWorker registerClientWorker = new RegisterClientWorker();
            Thread registerWorkerThread = new Thread(registerClientWorker);
            registerWorkerThread.start();

            // 使用 join, 保证注册先行于心跳发送
            registerWorkerThread.join();

            // 2.启动心跳线程进行工作
            new HeartbeatClientWorker().start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 负责向 register-server 发起注册申请的“线程”
     */
    @Data
    @ToString
    private class RegisterClientWorker implements Runnable {
        @Override
        public void run() {
            // 注册
            // 应该是获取当前机器的信息
            // 包括当前机器的ip地址、hostname，以及你配置这个服务监听的端口号
            // 从配置文件里可以拿到
            RegisterRequest registerRequest = new RegisterRequest();
            registerRequest.setServiceName(SERVICE_NAME);
            registerRequest.setIp(IP);
            registerRequest.setHostname(HOSTNAME);
            registerRequest.setPort(PORT);
            registerRequest.setServiceInstanceId(serviceInstanceId);

            RegisterResponse registerResponse = httpSender.register(registerRequest);
            System.out.println("服务注册的结果是：" + registerResponse.getStatus() + "......");
        }
    }

    /**
     * 负责向 register-server 发起心跳的线程
     */
    @Data
    @ToString
    private class HeartbeatClientWorker extends Thread {
        @Override
        public void run() {
            // 发送心跳
            // 如果说注册成功了，就进入while true死循环
            HeartbeatRequest heartbeatRequest = new HeartbeatRequest();
            heartbeatRequest.setServiceName(SERVICE_NAME);
            heartbeatRequest.setServiceInstanceId(serviceInstanceId);
            HeartbeatResponse heartbeatResponse = null;

            while (true) {
                try {
                    heartbeatResponse = httpSender.heartbeat(heartbeatRequest);
                    System.out.println("心跳的结果为：" + heartbeatResponse.getStatus() + "......");
                    // 休眠 30s, 即每隔 30s 发送一次心跳
                    Thread.sleep(30 * 1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
